package com.xjrsoft.module.workflow.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xjrsoft.common.result.Response;
import com.xjrsoft.core.secure.utils.SecureUtil;
import com.xjrsoft.core.tool.utils.CollectionUtil;
import com.xjrsoft.core.tool.utils.FlowableUtil;
import com.xjrsoft.core.tool.utils.StringPool;
import com.xjrsoft.core.tool.utils.StringUtil;
import com.xjrsoft.module.base.entity.XjrBaseTempfield;
import com.xjrsoft.module.base.entity.XjrBaseUser;
import com.xjrsoft.module.base.service.IXjrBaseTempfieldService;
import com.xjrsoft.module.base.utils.OrganizationCacheUtil;
import com.xjrsoft.module.workflow.dto.GetPageListNwfMonitorDto;
import com.xjrsoft.module.workflow.service.IXjrNwfMonitorService;
import com.xjrsoft.module.workflow.service.IXjrNwfTaskService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.Optional;

@Slf4j
@ControllerAdvice
@AllArgsConstructor
@RestController
@RequestMapping("/workflow-monitor")
@Api(value = "工作流流程监控控制器", tags = "工作流流程监控控制器")
public class NwfMonitorController {

    IXjrNwfMonitorService nwfMonitorService;

    TaskService taskService;

    IXjrNwfTaskService nwfTaskService;

    IXjrBaseTempfieldService xjrBaseTempfieldService;

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2021/1/26
     * @Param:[dto]
     * @return:com.xjrsoft.common.result.Response
     * @Description:已完成任务
     */
    @SneakyThrows
    @GetMapping("/finished-tasks")
    @ApiOperation(value = "已完成任务")
    public Response finishedTask(GetPageListNwfMonitorDto dto) {
        return Response.ok(nwfMonitorService.finishedProcess(dto));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2021/1/26
     * @Param:[dto]
     * @return:com.xjrsoft.common.result.Response
     * @Description:未完成任务
     */
    @SneakyThrows
    @GetMapping("/unfinished-tasks")
    @ApiOperation(value = "未完成任务")
    public Response unfinishedTask(GetPageListNwfMonitorDto dto) {
        return Response.ok(nwfMonitorService.unfinishedProcess(dto));
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2021/1/26
     * @Param:[processId]
     * @return:com.xjrsoft.common.result.Response
     * @Description:暂停流程
     */
    @PostMapping("/suspend-process")
    @ApiOperation(value = "暂停工作流")
    @ApiImplicitParam(name = "processInstanceId", dataType = "string", paramType = "query",value = "流程实例id")
    public Response suspendProcess(String processInstanceId) {
        FlowableUtil.suspendProcessInstance(processInstanceId,"流程被挂起",1);
        return Response.ok();
    }

    /**
    * @Author:湘北智造-框架开发组
    * @Date:2021/1/26
    * @Param:[processInstanceId]
    * @return:com.xjrsoft.common.result.Response
    * @Description:激活流程
    */
    @PostMapping("/activate-process")
    @ApiOperation(value = "激活流程")
    @ApiImplicitParam(name = "processInstanceId", dataType = "string", paramType = "query",value = "流程实例id")
    public Response activateProcess(String processInstanceId) throws Exception {
        FlowableUtil.activateProcessInstance(processInstanceId);
        return Response.ok();
    }

    /**
    * @Author:湘北智造-框架开发组
    * @Date:2021/1/26
    * @Param:[taskId, userId]
    * @return:com.xjrsoft.common.result.Response
    * @Description:任务添加审批人
    */
    @PutMapping("/assign")
    @ApiOperation(value = "任务添加审批人")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", dataType = "string", paramType = "query",value = "添加的用户id"),
            @ApiImplicitParam(name = "taskId", dataType = "string", paramType = "query",value = "流程任务id")
    })
    public Response assign(String taskId, String userId){
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if(task==null){
            return Response.notOk("此用户任务不存在或者已审批!!");
        }
        boolean suspended = task.isSuspended();
        if(suspended){
            return Response.notOk("该流程已终止，不能进行指派审核人操作！");
        }
        String[] userIds = userId.split(StringPool.COMMA);
        List<String> assaigns = nwfTaskService.getUserIdByTask(taskId);
        for (String id : userIds) {
            if (!assaigns.contains(id)) {
                FlowableUtil.assign(taskId, userId);
            }
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("currentUserId", SecureUtil.getUserId());
        JSONArray jsonArray = new JSONArray();
        for (String id : userIds) {
            jsonArray.add(id);
        }
        jsonObject.put("addAssigns",jsonArray);
        //保存指派审核人信息
        XjrBaseTempfield xjrBaseTempfield = new XjrBaseTempfield();
        xjrBaseTempfield.setFkey(taskId);
        xjrBaseTempfield.setType("39");
        xjrBaseTempfield.setFvalue(jsonObject.toJSONString());
        xjrBaseTempfield.setCreateTime(new Date());
        xjrBaseTempfieldService.save(xjrBaseTempfield);
        return Response.ok();
    }

    /**
     * @Author:湘北智造-框架开发组
     * @Date:2021/1/26
     * @Param:[taskId, userId]
     * @return:com.xjrsoft.common.result.Response
     * @Description:获取任务审批人
     */
    @GetMapping("/getAssign")
    @ApiOperation(value = "获取任务审批人")
    @ApiImplicitParam(name = "taskId", dataType = "string", paramType = "query",value = "流程任务id")
    public Response assign(String taskId){
        List<XjrBaseUser> listCaches = OrganizationCacheUtil.getListCaches(OrganizationCacheUtil.USER_LIST_CACHE_KEY);
        if(StringUtil.isBlank(taskId)){
            return Response.notOk("此流程没有正在审批的用户任务");
        }
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if(task==null){
            return Response.notOk("此用户任务不存在或者已审批!!");
        }
        JSONArray users = new JSONArray();
        List<String> userIds = nwfTaskService.getUserIdByTask(taskId);
        if(CollectionUtil.isNotEmpty(userIds)){
            for (String userId : userIds) {
                Optional<XjrBaseUser> xjrBaseUserOptional = listCaches.stream().filter(s -> StringUtil.equals(userId, s.getUserId())).findFirst();
                if(xjrBaseUserOptional.isPresent()){
                    JSONObject userObj = new JSONObject();
                    XjrBaseUser xjrBaseUser =  xjrBaseUserOptional.get();
                    String realName = xjrBaseUser.getRealName();
                    userObj.put("userId",userId);
                    userObj.put("name",StringUtil.isBlank(realName)?xjrBaseUser.getAccount():realName);
                    users.add(userObj);
                }
            }
        }
        return Response.ok(users);
    }
}
